package com.anp.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.anp.business.common.BankBusinessConfig;
import com.anp.business.common.Constant;
import com.anp.business.entity.dto.*;
import com.anp.business.service.IBankBusinessService;
import com.anp.business.utils.AxinConnection;
import com.anp.business.utils.DateFormatters;
import com.anp.business.utils.Sha1Util;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;

/**
 * @author yicky zhang
 * @create 2018-09-06 下午3:33
 * @desc
 **/
@Service
@Transactional(rollbackFor = Exception.class)
public class BankBusinessServiceImpl implements IBankBusinessService {
    private static final String TOKEN_URL = "/token/access";
    private static final String CERTIFY_URL = "/datacenter/smartverification/bankcard/verify";
    private static Logger logger = LoggerFactory.getLogger(BankBusinessServiceImpl.class);

    @Autowired
    private BankBusinessConfig config;

    @Override
    public CertifyResp certify(String cardType, String cardNo, String name, String phoneNo, String idCard) throws Exception {
        long currentSec = System.currentTimeMillis() / 1000;
        long timeZone = currentSec - Constant.startSecond;
        if (StringUtils.isBlank(Constant.zhihuiToken) || timeZone > 60 * 50) {
            TokenResp tokenResp = getToken();
            refreshToken(tokenResp);
        }
        CertifyResp certifyResp = connectToCertify(cardType, cardNo, name, phoneNo, idCard);
        logger.info("certifyResp:" + JSON.toJSONString(certifyResp));
        return certifyResp;
    }

    @Override
    public TokenResp getToken() throws Exception {
        String appId = config.getAppId();
        String appKey = config.getAppKey();
        String reqStr = assembleTokenReq(appId, appKey);
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json;charset=utf-8");
        headers.put("Accept", "application/json");

        AxinConnection connection = new AxinConnection();
        String respStr = null;
        respStr = connection.postUrl(config.getUrl() + TOKEN_URL, reqStr, headers);
        return JSON.parseObject(respStr, TokenResp.class);
    }

    private String assembleTokenReq(String appId, String appKey) {
        TokenReq tokenReq = new TokenReq();
        String nonece = String.valueOf(System.currentTimeMillis());
        String timeStamp = DateFormatters.format(new Date(), DateFormatters.ISO_DATE_TIME_FORMAT);
        tokenReq.setAppId(appId);
        tokenReq.setNonce(nonece);
        tokenReq.setTimestamp(timeStamp);
        tokenReq.setSignature(Sha1Util.encode(appId + timeStamp + nonece + appKey));
        return JSON.toJSONString(tokenReq);
    }

    private void refreshToken(TokenResp tokenResp) throws Exception {
        if (TokenResp.ERROR_CODE_SUCCESS.equals(tokenResp.getErrCode())) {
            System.out.println("tokenResp.getAccessToken():" + tokenResp.getAccessToken());
            logger.info(String.format("token为空，自动获取token:%s", StringUtils.isNotBlank(tokenResp.getAccessToken()) ? tokenResp.getAccessToken() : null));
            logger.info(String.format("失效时间expiresIn[%s]", tokenResp.getExpiresIn()));
            //设置token
            Constant.zhihuiToken = tokenResp.getAccessToken();
            Constant.startSecond = System.currentTimeMillis() / 1000;
        } else {
            throw new Exception("初始化token为空，且获取token失败");
        }
    }

    private CertifyResp connectToCertify(String cardType, String cardNo, String name, String phoneNo, String idCard) throws Exception {
        String reqStr = assembleCertifyReq(cardType, cardNo, name, phoneNo, idCard);
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json;charset=utf-8");
        headers.put("Authorization", Constant.zhihuiToken);
        headers.put("Accept", "application/json");
        AxinConnection connection = new AxinConnection();
        String respStr = connection.postUrl(config.getUrl() + CERTIFY_URL, reqStr, headers);
        CertifyResp certifyResp = null;
        if ("HTTP/1.1 412".equals(respStr)) {
            certifyResp = new CertifyResp();
            certifyResp.setErrCode("HTTP/1.1 412");
            certifyResp.setErrInfo("先决条件验证失败,token可能失效");
            return certifyResp;
        }
        certifyResp = JSON.parseObject(respStr, CertifyResp.class);
        return certifyResp;
    }

    private String assembleCertifyReq(String cardType, String cardNo, String name, String phoneNo, String idCard) {
        CertifyReq certifyReq = new CertifyReq();
        CertifyReqData certifyReqData = new CertifyReqData();
        certifyReqData.setCardNo(cardNo);
        certifyReqData.setName(StringUtils.isNotBlank(name) ? name : null);
        certifyReqData.setPhoneNo(StringUtils.isNotBlank(phoneNo) ? phoneNo : null);
        certifyReqData.setDcType(StringUtils.isNotBlank(cardType) ? cardType : null);
        certifyReqData.setPersonalMandate(CertifyReqData.PERSONAL_MANDATA);
        if (StringUtils.isNotBlank(idCard)) {
            certifyReqData.setCertType(CertifyReqData.CERTTYPE_ID_CARD);
            certifyReqData.setCertNo(idCard);
        }
        certifyReq.setData(certifyReqData);
        return JSON.toJSONString(certifyReq);
    }

}


